#!/usr/bin/python3
# -*- coding:utf-8 -*-
""""
   @Author: 叶建伟
   @Email: yejw46507@hundsun.com
   @Time: 2022/6/14 19:32
   @File: suspicious_rule_config.py
"""
import re
import time

from qturboframe.lib.utils.by import By

from AmlScripts.BasicFunction.common_test_prepare import common_test_prepare
from BladeFerm.hui2_app import FE
from BladeFerm.Lib.Common import logger
from CommonScripts.common_method_hui_two import open_menu
from qturboframe.lib.webdriver.exceptions import SeleniumError


@common_test_prepare
def suspicious_trade_rule_modify(input_data=None, ui_expect=None):
    # 打开菜单
    open_menu({'子系统名称': '反洗钱系统', '菜单名称': '可疑交易管理/可疑交易规则'})
    # 选择规则
    rule_name = input_data.pop('可疑交易规则', '')
    _open_target_rule(rule_name)
    input_data = _deal_input_data(input_data)
    ui_expect = _deal_input_data(ui_expect)
    # 修改基础信息  断言结果
    if input_data.get('基础信息', None):
        modify_base_info(input_data.get('基础信息'))
    if ui_expect.get('基础信息', None):
        _check_modify_result(ui_expect.get('基础信息'), tag='th')
    # 修改配置信息  断言结果
    if input_data.get('参数配置', None):
        modify_config_info(input_data.get('参数配置'))
    if ui_expect.get('参数配置', None):
        _check_modify_result(ui_expect.get('参数配置'), tag='td')
    # 弹框内容检测  反例
    if ui_expect.get("弹框", None):
        _check_failure_message(ui_expect.get("弹框"))


def _deal_input_data(input_data):
    newDict = dict()
    basicDict = dict()
    paramsDict = dict()
    for key, value in input_data.items():
        if key.startswith("基础信息/"):
            leftKey, rightKey = key.split('/')
            basicDict[rightKey] = value
        elif key.startswith("参数配置/"):
            leftKey, rightKey = key.split('/')
            paramsDict[rightKey] = value
        else:
            newDict[key] = value
    if basicDict:
        newDict['基础信息'] = basicDict
    if paramsDict:
        newDict['参数配置'] = paramsDict
    logger.info(f"_deal_input_data: {newDict}")
    return newDict


def _open_target_rule(ruleName):
    inputEle = FE.input_type({By.XPATH: '//div[contains(@class,"search-item")]/div[contains(@class,"h-input-wrapper")]'})
    inputEle.set_value(ruleName)
    select = FE.list({By.XPATH: '//ul[@class="h-tree"]'})
    select.click(idname={By.XPATH: f'//li/div[@class="h-tree-item"]//span[contains(text(), "{ruleName}")]'})
    logger.info(f"打开可疑规则：{ruleName}")


def _button_option(base='基础信息', option='修改'):
    target = FE.list(idname={By.XPATH: f'//h2[@class="base-title" and contains(text(), "{base}")]'})
    target.foud_target(idname={By.XPATH: './span'})
    target.click(option)
    logger.info(f"操作位置：{base}，操作动作：{option}")


def modify_base_info(input_data=None):
    _button_option("基础信息", "修改")
    for key, value in input_data.items():
        if key in ['是否启用', '可疑特征']:
            selectXpath = f'//th[contains(text(),"{key}")]/../td//div[contains(@class,"h-selectTable-single")]'
            selectElement = FE.select_table(idname={By.XPATH: selectXpath})
            selectElement.set_value_for_single(value)
        elif key == '周期预警':
            selectXpath = f'(//th[contains(text(),"{key}")]/../td//div[contains(@class,"h-selectTable-single")])[1]'
            selectElement = FE.select_table(idname={By.XPATH: selectXpath})
            selectElement.set_value_for_single(value)
        elif key == '描述':
            textXpath = f'//th[contains(text(),"{key}")]/../td//div[contains(@class,"h-input-wrapper")]/textarea'
            textArea = FE.textarea(idname={'xpath': textXpath})
            textArea.set_value(value)
        else:
            logger.warning(f"得到了不期望的键：{key}！")
        logger.info(f"基础信息: {key} 设置为 {value}!")
    _button_option("基础信息", input_data.get("操作", "保存"))


def modify_config_info(input_data=None):
    _button_option("参数配置", "修改")
    next_option = input_data.pop("操作", "保存")
    __input_element = "h-input-wrapper"
    __select_single_element = "h-selectTable-single"
    __select_multiple_element = "h-selectTable-multiple"
    for key, value in input_data.items():
        if value == "":
            continue
        ele = FE.driver.find_element_by_attribute(By.XPATH, f'//td[contains(text(),"{key}")]/../td/div/div')
        ele_class = ele.get_attribute("class")
        if len(ele_class) == 0:
            ele = ele.find_element_by_attribute(By.XPATH, f'./div')
            ele_class = ele.get_attribute("class")
        logger.info(f'参数配置： {key} 设置为 {value}')
        if __input_element in ele_class:
            input2 = FE.input_type(idname={By.XPATH: f'.'}, father=ele)
            input2.set_value(value)
        elif __select_single_element in ele_class:
            select = FE.select_table(idname={By.XPATH: f'.'}, father=ele)
            select.set_value_for_single(value)
        elif __select_multiple_element in ele_class:
            values = value.split(',')
            select = FE.select_table(idname={By.XPATH: f'.'}, father=ele)
            select.set_value_for_multiple(values)
        else:
            logger.warning(f"不支持的的操作类型！")
    _button_option("参数配置", next_option)


# 结果检查
def _check_modify_result(ui_expect: dict, tag='th'):
    time.sleep(0.5)
    for key, value in ui_expect.items():
        rowXpath = f'//{tag}[contains(text(),"{key}")]/../td/span'
        tdElement = FE.driver.find_element_by_attribute(By.XPATH, rowXpath, timeout=1)
        tdText = tdElement.get_attribute('innerHTML')
        if re.search(value, tdText):
            logger.info(f"检查项目 {key} 的修改结果是 {value}， 符合期望！")
        else:
            error_info = f"检查项目 {key} 的修改结果是 {tdText}， 不符合期望 {value}！"
            logger.error(error_info)
            raise SeleniumError(error_info)


# 反例检查
def _check_failure_message(error_msg: str):
    msg_element = FE.driver.find_elements_by_attribute(By.CSS_SELECTOR, "div.h-message-notice", timeout=3)
    if msg_element:
        span_element = msg_element[0].find_element_by_attribute(By.XPATH, ".//span")
        text = span_element.text.strip()
        if re.search(error_msg, text):
            logger.info(f"监测到符合期望的弹框，内容为:{text}")
        else:
            logger.error(f'检测到弹框，但是内容不符合期望！')
            raise SeleniumError(f'检测到弹框，但是内容不符合期望！')
    else:
        error_info = "未检测到期望弹框，请检查！"
        logger.error(error_info)
        raise SeleniumError(error_info)